package org.example.domain.user_raffle.service.Impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.example.domain.user_raffle.model.entity.ActivityEntity;
import org.example.domain.user_raffle.model.entity.ActivityStrategyPrizeEntity;
import org.example.domain.user_raffle.model.entity.PrizeEntity;
import org.example.domain.user_raffle.model.entity.StockZeroTaskEntity;
import org.example.domain.user_raffle.repository.IUserRaffleRepo;
import org.example.domain.user_raffle.service.IUserRaffleService;
import org.example.domain.user_raffle.service.algorithm.IRaffleAlgorithm;
import org.example.domain.user_raffle.service.algorithm.Impl.RaffleAlgorithmON;
import org.example.domain.user_raffle.service.engine.RaffleChainFactory;
import org.example.types.common.RedisKeysPrefix;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author lxc18
 * @date 2025/3/29 17:00
 * @description IUserRaffleServiceImpl
 */
@Service
@Slf4j
public class IUserRaffleServiceImpl implements IUserRaffleService {
    @Resource
    private IUserRaffleRepo userRaffleRepo;
    @Resource
    private RaffleChainFactory raffleChainFactory;
    @Resource
    private IRaffleAlgorithm raffleAlgorithm;

    @Override
    public boolean isActivityValid(Long activityId) {
        ActivityEntity activityEntity = userRaffleRepo.queryActivityById(activityId);
        if (activityEntity != null) {
            // 活动是否有效
            if (activityEntity.getStartTime().isBefore(LocalDateTime.now()) && activityEntity.getEndTime().isAfter(LocalDateTime.now())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean isUserQuotaValid(Long activityId, Long userId) {
        int userQuota = userRaffleRepo.queryUserQuota(activityId, userId);
        if (userQuota > 0) {
            return true;
        }
        return false;
    }

    @Override
    public Long participateInRaffle(Long activityId, Long userId,int usedQuota) {
        Map<String, ActivityStrategyPrizeEntity> strategyPrizeEntities = userRaffleRepo.queryAllStrategy(activityId);
        List<Long> prizeIds = raffleChainFactory.process(userId, activityId,usedQuota,strategyPrizeEntities);
        //获得奖品的概率
        //批量查询奖品
        List<Pair<Long, BigDecimal>> prizeEntities = userRaffleRepo.queryPrizeByIds(prizeIds);
        //选择O(N)算法
        Long prizeId = raffleAlgorithm.doRaffle(prizeEntities);
        //扣减库存
        Long result = userRaffleRepo.deductPrizeStock(prizeId);
        //postProcess
        prizeId = userRaffleRepo.postProcess(userId, activityId, result, prizeId);
        //保底奖品
        ActivityStrategyPrizeEntity guarantee = strategyPrizeEntities.get("guarantee");
        if(guarantee.getPrizeIds().contains(prizeId.toString())){
            //如果是保底奖品，需要将用户的已使用积分清零
            String config = guarantee.getConfig();
            if (config!=null){
                int guaQuota = Integer.parseInt(config);
                int quota = Math.min(usedQuota, guaQuota);
                try {
                    clearUsedQuota(activityId, userId,quota);
                } catch (Exception e) {
                    log.error("clearUsedQuota error,activityId={},userId={},quota={}",activityId,userId,quota);
                }
            }

        }
        return prizeId;
    }

    @Override
    public Long processResult(int status) {
        return null;
    }

    //是否是保底奖品
    @Override
    public boolean isGuaranteePrize(Long activityId,Long prizeId){
        //TOD
        return userRaffleRepo.isGuaranteePrize(activityId, prizeId);
    }
    @Override
    public int deductUserQuotaAndAddUsedQuota(Long activityId, Long userId) {

        return userRaffleRepo.deductUserQuotaAndAddUsedQuota(activityId, userId);
    }

    @Override
    public boolean addUserRaffleRecord(Long activityId, Long userId, Long prizeId) {
        return userRaffleRepo.addUserRaffleRecord(activityId, userId, prizeId);
    }

    @Override
    public List<Long> getAllPrizeIds() {
        return userRaffleRepo.getAllPrizeIds();
    }

    @Override
    public void decrPrizeStock(Long prizeId,int size) {
        userRaffleRepo.decrPrizeStock(prizeId,size);
    }

    @Override
    public PrizeEntity queryPrizeById(Long prizeId) {
        return userRaffleRepo.queryPrizeById(prizeId);

    }

    @Override
    public void clearUsedQuota(Long activityId, Long userId,int quota) {
        userRaffleRepo.clearUsedQuota(activityId, userId,quota);
    }

    @Override
    public void updateStockToZero(Long prizeId) {
        userRaffleRepo.updateStockToZero(prizeId);
    }

    @Override
    public void updateStatusSuccess(Long id) {
        userRaffleRepo.updateStatusSuccess(id);
    }

    @Override
    public void updateStatusFailed(Long id) {
        userRaffleRepo.updateStatusFailed(id);
    }

    @Override
    public boolean isTaskStockZero(Long id) {
        return userRaffleRepo.isTaskStockZero(id);
    }

    @Override
    public List<StockZeroTaskEntity> getAllFailedTaskIds() {
        return userRaffleRepo.getAllFailedTaskIds();
    }
}
